package config

import (
	"context"
	"gitee.com/bobo-rs/idea-space-framework/framework/dao"
	"gitee.com/bobo-rs/idea-space-framework/framework/model"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
)

// ProcessConfigScan 处理并扫描业务配置
func (c *sConfig) ProcessConfigScan(ctx context.Context, where, scan interface{}) error {
	if where == nil || g.IsNil(where) {
		return gerror.New(`缺少请求参数`)
	}
	return dao.Config.Ctx(ctx).Where(where).Scan(scan)
}

// ProcessConfigByGroup 根据配置组名获取配置组数据
func (c *sConfig) ProcessConfigByGroup(ctx context.Context, name string, group interface{}) error {
	if len(name) == 0 {
		return gerror.New(`缺少配置组名`)
	}
	return c.ProcessConfigScan(ctx, g.Map{
		dao.Config.Columns().GroupName: name,
	}, group)
}

// ProcessConfigMapByGroup 根据配置组获取配置组MAP
func (c *sConfig) ProcessConfigMapByGroup(ctx context.Context, name string) (map[string]model.ConfigNameValueItem, error) {
	var (
		list     = make([]model.ConfigNameValueItem, 0)
		groupMap = make(map[string]model.ConfigNameValueItem)
	)
	// 获取数据
	err := c.ProcessConfigByGroup(ctx, name, &list)
	if err != nil {
		return nil, err
	}
	// 暂时数据
	if len(list) == 0 {
		return nil, gerror.New(`暂无数据`)
	}
	// 迭代处理MAP
	for _, item := range list {
		groupMap[item.Name] = item
	}
	return groupMap, nil
}

// ProcessTotal 统计配置总数
func (c *sConfig) ProcessTotal(ctx context.Context, where interface{}) (int, error) {
	if where == nil || g.IsNil(where) {
		return 0, gerror.New(`缺少请求参数`)
	}
	return dao.Config.Ctx(ctx).Where(where).Count()
}

// ProcessExists 检测配置是否存在
func (c *sConfig) ProcessExists(ctx context.Context, where interface{}) (bool, error) {
	total, err := c.ProcessTotal(ctx, where)
	if err != nil {
		return false, err
	}
	return total > 0, nil
}

// ProcessExistsByGroupName 根据配置组名检测配置是否存在
func (c *sConfig) ProcessExistsByGroupName(ctx context.Context, groupName string) bool {
	b, _ := c.ProcessExists(ctx, g.Map{
		dao.Config.Columns().GroupName: groupName,
	})
	return b
}

// ProcessExistsByGroupId 根据配置组ID检测配置是否存在
func (c *sConfig) ProcessExistsByGroupId(ctx context.Context, groupId uint) bool {
	b, _ := c.ProcessExists(ctx, g.Map{
		dao.Config.Columns().GroupId: groupId,
	})
	return b
}

// ProcessConfigValueByNameAndGroup 根据配置名和配置组获取配置值
func (c *sConfig) ProcessConfigValueByNameAndGroup(ctx context.Context, name, groupName string) (*string, error) {
	if len(name) == 0 {
		return nil, gerror.New(`缺少配置名`)
	}
	var (
		where = g.Map{
			dao.Config.Columns().Name: name,
		}
		item = model.ConfigNameValueItem{}
	)
	// 携带组名
	if len(groupName) > 0 {
		where[dao.Config.Columns().GroupName] = groupName
	}
	err := c.ProcessConfigScan(ctx, where, &item)
	if err != nil {
		return nil, err
	}
	return &item.Value, nil
}

// ProcessConfigIdByNameAndGroup 通过配置名和配置组ID获取配置ID
func (c *sConfig) ProcessConfigIdByNameAndGroupId(ctx context.Context, name []string, groupId []uint) (map[string]uint, error) {
	if len(name) == 0 || len(groupId) == 0 {
		return nil, gerror.New(`缺少配置名和配置组`)
	}
	var (
		where = g.Map{
			dao.Config.Columns().Name:    name,
			dao.Config.Columns().GroupId: groupId,
		}
		idMap = make(map[string]uint)
		list  []model.ConfigIdByNameAndGroupItem
	)
	err := c.ProcessConfigScan(ctx, where, &list)
	if err != nil {
		return nil, err
	}
	// 是否存在
	if len(list) == 0 {
		return nil, gerror.New(`暂无数据`)
	}
	// 迭代数据MAP
	for _, item := range list {
		idMap[item.GroupName+item.Name] = item.Id
	}
	return idMap, nil
}

// ProcessConfigDetailMapByName 通过配置名获取配置详情MAP
func (c *sConfig) ProcessConfigDetailMapByName(ctx context.Context, name []string) (map[string]model.ConfigIdByNameAndGroupItem, error) {
	if len(name) == 0 {
		return nil, gerror.New(`缺少配置名和配置组`)
	}
	var (
		where = g.Map{
			dao.Config.Columns().Name: name,
		}
		idMap = make(map[string]model.ConfigIdByNameAndGroupItem)
		list  []model.ConfigIdByNameAndGroupItem
	)
	err := c.ProcessConfigScan(ctx, where, &list)
	if err != nil {
		return nil, err
	}
	// 是否存在
	if len(list) == 0 {
		return nil, gerror.New(`暂无数据`)
	}
	// 迭代数据MAP
	for _, item := range list {
		idMap[item.Name] = item
	}
	return idMap, nil
}
